﻿namespace YunQue.WebApi.Middlewares
{
    /// <summary>
    /// 接口权限中间件
    /// </summary>
    public class APIPermissionMiddleware
    {
        private readonly RequestDelegate _next;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="next"></param>
        public APIPermissionMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        /// <summary>
        /// invoke
        /// </summary>
        /// <param name="context"></param>
        /// <param name="userContext"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task InvokeAsync(HttpContext context, UserContext userContext)
        {
            //检测是否需要验证身份信息
            var url = context.Request.Path.ToString();
            bool isAllowAnonymous = RouteAttributeCache.GetAllowAnonymousAttribute(url) != null;
            if (!isAllowAnonymous)
            {
                var apipermission = RouteAttributeCache.GetAPIPermissionAttribute(url);
                if(apipermission != null)
                {
                    List<string> permissions = new List<string>();
                    if (userContext.UserPermissions.IsNotNullOrEmpty()) permissions.AddRange(userContext.UserPermissions);
                    if (userContext.TenantPermissions.IsNotNullOrEmpty()) permissions.AddRange(userContext.TenantPermissions);
                    if (permissions.IsNullOrEmpty()) throw new Exception("无权限访问该接口");
                    var hasPermission = false;
                    switch(apipermission.OpreationType)
                    {
                        case OpreationType.And:
                            hasPermission = permissions.All(p => apipermission.PermissionCodes.Contains(p));
                            break;
                        case OpreationType.Or:
                            hasPermission = permissions.Any(p => apipermission.PermissionCodes.Contains(p));
                            break;
                    }
                    if (!hasPermission) throw new Exception("无权限访问该接口");
                }
            }
            await _next(context);
        }
    }
}
